#ifdef __APPLE__
	#include<OpenCL/opencl.h>
#else
	#include<CL/cl.h>
#endif

#ifndef __FFTZ__
	#define NO_TWIDDLE_LENGTH 4096
	#define NO_TWIDDLE_LENGTH_LOG_BY_2 12
	#define FFTZ_PI 3.1415926535897932384626433832795028841971693993751
	#define __FFTZ__
#endif

typedef struct _FftzEnv{
	cl_platform_id* platforms;
	cl_platform_id* platform;
	cl_device_id* devices;
	cl_device_id* device;
	cl_context context;
	cl_command_queue queue;
}FftzEnv;

typedef struct _FftzKernel{
	cl_kernel kernel;
	int radix;
	size_t groupSize;
	size_t groupSizeMul;
	size_t groupSizeSelected;
}FftzKernel;

typedef struct _FftzFactor{
	float* data;
	int dataSize;
}FftzFactor;

typedef struct _FftzStep{
	int length;
	int lengthLog;
	int partTotalLength;
	int partTotalLengthLog;
	int type;
	FftzKernel* kernel;
	FftzFactor* factor;
}FftzStep;

typedef struct _FftzPlan{
	int length;
	int lengthLog;
	int numKernels;
	int numFactors;
	int maxFactorDataSize;
	int numSteps;
	FftzKernel* kernels;
	FftzFactor* factors;
	FftzStep* steps;
}FftzPlan;


//functions provided by funs.c
extern int initFftzEnv(FftzEnv* cl);
extern int releaseFftzEnv(FftzEnv* cl);
extern int getFftzKernelFromSource(FftzEnv* cl, char* source_str, char* fun_name, FftzKernel* ke);
extern int releaseFftzKernel(FftzKernel* ke);
extern int initFftzPlan(FftzEnv* cl, FftzPlan* plan, int I);
extern int releaseFftzPlan(FftzPlan* plan);
extern int fftzRun(FftzEnv* cl, FftzPlan* plan, float* data0);

//variables provided by kernels.c
extern char* strKernelR2;
extern char* strKernelR4;
extern char* strKernelR8;
extern char* strKernelTwiddle;
extern char* strKernelPermutation;
